﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
<div id="prototypeout"></div>
<script type="text/javascript">
   function extend(destination, source) {
        for (var property in source) {
            destination[property] = source[property];
        }
    }
    var a = { test: function() { alert("in {}"); } };    // {}定义的对象没有 prototype

    extend(a, { test: function() { alert(" {} extend"); } }); //extend后依然没有prototype
    //a.test();

    a.prototype = { test2: function() { alert(" prototype test2"); } };

    extend(a.prototype, { test: function() { alert(" prototype test"); } });//优先使用 非原型中的 方法。
     
    
    //a.prototype.test = function() { alert("in prototype"); };

    a.test();
    //a.test2(); //异常，证明{}对象中，添加的原型是没有意义的
    a.prototype.test();

    //再一个有原型的function
    function temp() {
        this.test = function() {
            alert("inner test");
        }
    }
    
    //temp.test();  //这里异常，说明只有实例化后才能调用。如下两句
    var b = new temp();
    b.test(); //这里可以调用了
    temp.prototype.test2 = function() { alert("test2 prototype 赋值方式。 在函数中"); }; //修改函数中的原型是充许的。
    b.test2();
    // b.prototype.test2 = function() { alert("test2 prototype 赋值方式 在对象中。"); }; //这里异常 说明对像没有原型。
    temp.prototype.test = function() { alert("prototype 赋值方式。"); };
    b.test(); //这里还是 inner test 与上一个对比可以看出来，优先使用了对象的方法，对象中没有时，才使用原型中的方法。

    extend(temp.prototype, { test2: function() { alert("test2 prototype extend方式。"); } });
    b.test2(); //这里可以看出 extend 的方式覆盖了 直接赋值方式，也就是说他们是等价的。

    var c = temp(); //这里 c 是undefind，必须要new一个对象。 除非有返回值。
    function temp2() {
        this.test = function() {
            alert("test in temp2");
        }
        return this;
    }
    var d = temp2();
    d.test(); //因为temp2 返回了自己，所以不用new也可以，不过这里的this就变质了，似乎成了window。
    var e = {};
    extend(e, temp); //这里e什么也没有得到，所以调用 e.test() 会发生异常。
    e = temp;
    var f = new e();
    f.test(); //这里是可以的，相当于为temp起了一个别名或是一个引用（可能对象才能叫引用）。
    temp.prototype.test3 = function() { alert("test3"); }; //这时b 和 f 都因为temp原型的修改 增加了 test3方法
    b.test3();
    f.test3();
    
    
    /***************************
    总结：
    对象和类的概念不多说了，从上面的例子可以看出来，用function的方式，其实是定义了一个类，需要 new 一个对象。
    {}则是一种简单的定义对象的方式。 类是有原型的，而对象没有。
    对象中字段和方法优先级高，可以覆盖类中的字段和方法。
    extend可以应用于对象，也可以应用于原型。
    
    全局。
    引用
    ***************************/

    
    
    
    
    debugger;
</script>
</body>
</html>
